package dbx

import (
	"gitee.com/zhongguo168a/gocodes/datax/dictx"
	"gitee.com/zhongguo168a/gocodes/myx/nowctrl"
	"sync"
)

func NewSaveGroup(key string) (obj *SaveGroup) {
	obj = &SaveGroup{
		key: key,
	}
	obj.IDictionary = dictx.New[string, int]()
	obj.createTime = nowctrl.Now()

	return
}

// SaveItem编号  -> 更新时间
type SaveGroup struct {
	dictx.IDictionary[string, int]

	mutex sync.RWMutex
	//
	key string
	//
	order bool
	//
	createTime int
}

func (saveMap *SaveGroup) GetSaveItem(delayItem *DelayItem) *SaveItem {
	item := saveRoot.saveResp.MustGet(delayItem.Ident)
	if item == nil {
		return nil
	}
	if !saveMap.Has(delayItem.Ident) {
		saveMap.Set(item.Ident, nowctrl.Now())
	}
	return item
}

func (saveMap *SaveGroup) NewSaveItem(delayItem *DelayItem) *SaveItem {
	var (
		item *SaveItem
	)
	item = saveRoot.saveResp.MustGet(delayItem.Ident)
	if item == nil {
		item = saveRoot.saveResp.NewSaveItem(delayItem)
	}
	saveMap.Set(item.Ident, nowctrl.Now())
	return item
}

func (saveMap *SaveGroup) DeleteSaveItem(objectKey string) {
	saveMap.Delete(objectKey)
	saveRoot.saveResp.Delete(objectKey)
}

func (saveMap *SaveGroup) GetOrNewSaveItem(delayItem *DelayItem) *SaveItem {
	var (
		item *SaveItem
	)
	item = saveMap.GetSaveItem(delayItem)
	if item == nil {
		item = saveMap.NewSaveItem(delayItem)
	}
	return item
}

// -----------------------------------------------------------------------------------
//  -----------------------------------------------------------------------------------
// -----------------------------------------------------------------------------------
func NewSaveGroupResp() (obj *SaveGroupResp) {
	obj = &SaveGroupResp{}
	obj.IDictionary = dictx.New[string, *SaveGroup]()
	obj.saveQueue = NewSaveQueue()
	obj.OnSet(func(key string, value *SaveGroup) {
		obj.saveQueue.Add(value)
		obj.saveQueue.Sort(byPriority)
	})
	obj.OnDelete(func(key string, value *SaveGroup) {
		index := obj.saveQueue.IndexOf(value)
		if index != -1 {
			obj.saveQueue.Remove(index)
		}
	})
	return
}

type SaveGroupResp struct {
	dictx.IDictionary[string, *SaveGroup]

	// 按照时间排序的saveItem
	saveQueue *SaveQueue
	//
	mutex sync.Mutex
}

func (resp *SaveGroupResp) GetOrNew(key string) *SaveGroup {
	group, has := resp.Get(key)
	if !has {
		group = NewSaveGroup(key)
	}
	return group
}

func (resp *SaveGroupResp) ListByTime(checkTime bool, saveMinTime int) (groups []*SaveGroup) {
	resp.mutex.Lock()
	defer resp.mutex.Unlock()

	now := nowctrl.Now()
	if checkTime {
		saveQueue := resp.saveQueue
		for {
			if saveQueue.Empty() {
				break
			}
			igroup, _ := saveQueue.Get(0)
			group := igroup.(*SaveGroup)
			dif := now - group.createTime + 1
			//fmt.Println("dif", dif, "| ", now, group.createTime)
			if dif < saveMinTime {
				break
			}

			saveQueue.Remove(0)
			resp.Delete(group.key)
			groups = append(groups, group)
		}
	} else {
		// 取所有
		values := resp.saveQueue.Values()
		for _, ival := range values {
			groups = append(groups, ival.(*SaveGroup))
		}
		resp.saveQueue.Clear()
		resp.Clear()
	}

	return
}
